import { Connection, ConnectOptions } from './base/connection';
import { prepareConnectOption } from './register';
import { PoolOptions, Pool } from './base/pool';
import {
  parseConnectOption,
  getDefaultPoolOptions,
  getPoolOptions,
} from './config';

/**
 * 连接数据库并返回一个连接池
 * @param {*} config
 */
export async function createConnection(cfgOrUrl?: string): Promise<Connection>;
export async function createConnection(
  options: ConnectOptions
): Promise<Connection>;
export async function createConnection(
  optOrUrlOrCfg?: ConnectOptions | string
): Promise<Connection>;
export async function createConnection(
  optOrUrlOrCfg?: ConnectOptions | string
): Promise<Connection> {
  const options = await parseConnectOption(optOrUrlOrCfg);
  prepareConnectOption(options);
  return options.provider!.getConnection(options);
}

export async function createPool(cfgKey?: string): Promise<Pool>;
export async function createPool(
  options: PoolOptions & {
    connection: ConnectOptions;
  }
): Promise<Pool>;
export async function createPool(
  optOrCfg?:
    | (PoolOptions & {
        connection: ConnectOptions;
      })
    | string
): Promise<Pool>;
export async function createPool(
  optOrCfg?:
    | (PoolOptions & {
        connection: ConnectOptions;
      })
    | string
): Promise<Pool> {
  let options:
    | PoolOptions & {
        connection: ConnectOptions;
      };
  if (!optOrCfg) {
    options = await getDefaultPoolOptions();
  } else if (typeof optOrCfg === 'string') {
    options = await getPoolOptions(optOrCfg);
    if (!options) {
      throw new Error(`Pool configure not found.`);
    }
  } else {
    options = optOrCfg;
  }
  prepareConnectOption(options.connection);
  return new Pool(options.connection.provider!, options, options.connection);
}
